// ============================================================================
//
// Copyright (C) 2006-2007 Dengues
//
// Google Group: http://groups.google.com/group/dengues
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.commons.notifications;

import java.util.List;

import org.dengues.commons.IDenguesSharedImage;
import org.dengues.commons.utils.ImageUtil;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.Section;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf 2008-1-6 qiang.zhang $
 * 
 */
public abstract class AbstractNotificationPopup extends PopupDialog {

    private static final int NUM_NOTIFICATIONS_TO_DISPLAY = 4;

    private List<AbstractNotification> notifications;

    private final FormToolkit toolkit;

    private Form form;

    private Composite sectionClient;

    private Rectangle bounds;

    /**
     * Qiang.Zhang.Adolf@gmail.com ConnectivityListNotificationPopup constructor comment.
     * 
     * @param parent
     */
    public AbstractNotificationPopup(Shell parent) {
        super(parent, PopupDialog.INFOPOPUP_SHELLSTYLE | SWT.ON_TOP, false, false, false, false, null, null);
        toolkit = new FormToolkit(parent.getDisplay());
    }

    public void setContents(List<AbstractNotification> notifications) {
        this.notifications = notifications;
    }

    @Override
    protected Control createContents(Composite parent) {
        getShell().setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
        return createDialogArea(parent);
    }

    @Override
    protected final Control createDialogArea(final Composite parent) {
        getShell().setText(getNotificationTitle());

        form = toolkit.createForm(parent);
        form.getBody().setLayout(new GridLayout());

        Section section = toolkit.createSection(form.getBody(), Section.TITLE_BAR);

        section.setText(getNotificationTitle());
        section.setLayout(new GridLayout());

        sectionClient = toolkit.createComposite(section);
        sectionClient.setLayout(new GridLayout(2, false));
        int count = 0;
        for (final AbstractNotification notification : notifications) {
            if (count < getNumbersToDisplay()) {
                Label notificationLabelIcon = toolkit.createLabel(sectionClient, ""); //$NON-NLS-1$
                notificationLabelIcon.setImage(notification.getNotificationKindImage());
                ImageHyperlink link = toolkit.createImageHyperlink(sectionClient, SWT.BEGINNING | SWT.WRAP);
                link.setText(notification.getLabel());
                link.setImage(notification.getNotificationImage());
                link.addHyperlinkListener(new HyperlinkAdapter() {

                    @Override
                    public void linkActivated(HyperlinkEvent e) {
                        notification.open();
                        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
                        if (window != null) {
                            Shell windowShell = window.getShell();
                            if (windowShell != null) {
                                windowShell.setMaximized(true);
                                windowShell.open();
                            }
                        }
                    }
                });

                String descriptionText = null;
                if (notification.getDescription() != null) {
                    descriptionText = notification.getDescription();
                }
                if (descriptionText != null) {
                    Label descriptionLabel = toolkit.createLabel(sectionClient, descriptionText);
                    GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(descriptionLabel);
                }
            } else {
                int numNotificationsRemain = notifications.size() - count;
                Hyperlink remainingHyperlink = toolkit.createHyperlink(sectionClient, numNotificationsRemain
                        + getNotificationsHiddenTitle(), SWT.NONE);
                GridDataFactory.fillDefaults().span(2, SWT.DEFAULT).applyTo(remainingHyperlink);
                remainingHyperlink.addHyperlinkListener(new HyperlinkAdapter() {

                    @Override
                    public void linkActivated(HyperlinkEvent e) {
                        // TaskListView.openInActivePerspective().setFocus();
                        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
                        if (window != null) {
                            Shell windowShell = window.getShell();
                            if (windowShell != null) {
                                windowShell.setMaximized(true);
                                windowShell.open();
                            }
                        }
                    }
                });
                break;
            }
            count++;
        }

        section.setClient(sectionClient);

        ImageHyperlink hyperlink = new ImageHyperlink(section, SWT.NONE);
        toolkit.adapt(hyperlink, true, true);
        hyperlink.setBackground(null);
        hyperlink.setImage(ImageUtil.getImage(IDenguesSharedImage.PREFS_CONNSET));
        hyperlink.addHyperlinkListener(new HyperlinkAdapter() {

            @Override
            public void linkActivated(HyperlinkEvent e) {
                close();
            }
        });
        section.setTextClient(hyperlink);

        parent.pack();
        return form;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getNumbersToDisplay".
     * 
     * @return
     */
    protected int getNumbersToDisplay() {
        return NUM_NOTIFICATIONS_TO_DISPLAY;
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getNotificationTitle".
     * 
     * @return
     */
    protected abstract String getNotificationTitle();

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getNotificationsHiddenTitle".
     * 
     * @return
     */
    protected abstract String getNotificationsHiddenTitle();

    /**
     * Initialize the shell's bounds.
     */
    @Override
    public void initializeBounds() {
        getShell().setBounds(restoreBounds());
    }

    private Rectangle restoreBounds() {
        bounds = getShell().getBounds();
        Rectangle maxBounds = null;

        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (window != null) {
            maxBounds = window.getShell().getMonitor().getClientArea();
        } else {
            // fallback
            Display display = Display.getCurrent();
            if (display == null)
                display = Display.getDefault();
            if (display != null && !display.isDisposed())
                maxBounds = display.getPrimaryMonitor().getClientArea();
        }

        if (bounds.width > -1 && bounds.height > -1) {
            if (maxBounds != null) {
                bounds.width = Math.min(bounds.width, maxBounds.width);
                bounds.height = Math.min(bounds.height, maxBounds.height);
            }
            // Enforce an absolute minimal size
            bounds.width = Math.max(bounds.width, 30);
            bounds.height = Math.max(bounds.height, 30);
        }

        if (bounds.x > -1 && bounds.y > -1 && maxBounds != null) {
            // bounds.x = Math.max(bounds.x, maxBounds.x);
            // bounds.y = Math.max(bounds.y, maxBounds.y);

            if (bounds.width > -1 && bounds.height > -1) {
                bounds.x = maxBounds.x + maxBounds.width - bounds.width;
                bounds.y = maxBounds.y + maxBounds.height - bounds.height;
            }
        }

        return bounds;
    }

    @Override
    public boolean close() {
        if (toolkit != null) {
            if (toolkit.getColors() != null) {
                toolkit.dispose();
            }
        }
        return super.close();
    }
}
